{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import json\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "params = {\n",
    "    'batch_size': 64,\n",
    "    'lr' : 0.001,\n",
    "    'max_sent_len': 20,\n",
    "    'epochs': 500,\n",
    "    'drops' : [0.1]\n",
    "         }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('./char_6.17.json', mode='r', encoding='utf-8') as f:\n",
    "    dicts = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "char2id = dicts['char2id']\n",
    "id2intent = dicts['id2intent']\n",
    "id2slot = dicts['id2slot']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "params['intent_num'] = len(id2intent)\n",
    "params['slot_num'] = len(id2slot)\n",
    "max_sent_len = params[\"max_sent_len\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# base model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"functional_1\"\n",
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "Input (InputLayer)              [(None, 20)]         0                                            \n",
      "__________________________________________________________________________________________________\n",
      "embedding (Embedding)           (None, 20, 32)       16000       Input[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "bidirectional (Bidirectional)   [(None, 20, 128), (N 37632       embedding[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "pre_intent (Dense)              (None, 55)           3575        bidirectional[0][1]              \n",
      "__________________________________________________________________________________________________\n",
      "pre_ner (Dense)                 (None, 20, 36)       4644        bidirectional[0][0]              \n",
      "==================================================================================================\n",
      "Total params: 61,851\n",
      "Trainable params: 61,851\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "text_inputs = tf.keras.layers.Input(shape=(20,),name='Input')\n",
    "embed = tf.keras.layers.Embedding(500,32)(text_inputs)\n",
    "bilstm = tf.keras.layers.Bidirectional(tf.keras.layers.GRU(64,return_sequences=True, return_state=True))(embed)\n",
    "pre_intent = tf.keras.layers.Dense(params['intent_num'],activation='sigmoid',name = 'pre_intent')(bilstm[1])\n",
    "pre_slot = tf.keras.layers.Dense(params['slot_num'],activation='sigmoid',name = 'pre_ner')(bilstm[0])\n",
    "model = tf.keras.Model(text_inputs,[pre_intent,pre_slot])\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.load_weights('./model_weight/model.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# conv model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"functional_1\"\n",
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "Input (InputLayer)              [(None, 20)]         0                                            \n",
      "__________________________________________________________________________________________________\n",
      "embedding (Embedding)           (None, 20, 32)       16000       Input[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "bidirectional (Bidirectional)   (None, 20, 128)      37632       embedding[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "layer_normalization (LayerNorma (None, 20, 128)      256         bidirectional[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "global_average_pooling1d (Globa (None, 128)          0           layer_normalization[0][0]        \n",
      "__________________________________________________________________________________________________\n",
      "layer_normalization_1 (LayerNor (None, 20, 128)      256         bidirectional[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "pre_intent (Dense)              (None, 55)           7095        global_average_pooling1d[0][0]   \n",
      "__________________________________________________________________________________________________\n",
      "pre_ner (Dense)                 (None, 20, 36)       4644        layer_normalization_1[0][0]      \n",
      "==================================================================================================\n",
      "Total params: 65,883\n",
      "Trainable params: 65,883\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "text_inputs = tf.keras.layers.Input(shape=(20,),name='Input')\n",
    "embed = tf.keras.layers.Embedding(500,32)(text_inputs)\n",
    "bilstm = tf.keras.layers.Bidirectional(tf.keras.layers.GRU(64,return_sequences=True))(embed)\n",
    "x_in = tf.keras.layers.LayerNormalization()(bilstm)\n",
    "x_conv = tf.keras.layers.GlobalAveragePooling1D()(x_in)\n",
    "pre_intent = tf.keras.layers.Dense(params['intent_num'],\\\n",
    "            activation='sigmoid',name = 'pre_intent')(x_conv)\n",
    "x_ner  = tf.keras.layers.LayerNormalization()(bilstm)\n",
    "pre_slot = tf.keras.layers.Dense(params['slot_num'],activation='sigmoid',name = 'pre_ner')(x_ner)\n",
    "model = tf.keras.Model(text_inputs,[pre_intent,pre_slot])\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.load_weights('./ner_model_weight/model_conv_621.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trans2labelid(vocab, labels, max_sent_len):\n",
    "    labels = [vocab[label] for label in labels]\n",
    "    if len(labels) < max_sent_len:\n",
    "        labels += [0] * (max_sent_len - len(labels))\n",
    "    else:\n",
    "        labels = labels[:max_sent_len]\n",
    "    return labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(x):\n",
    "    x = list(x)\n",
    "    pre_data = trans2labelid(char2id,x,max_sent_len)\n",
    "    pre_data = model.predict([pre_data])\n",
    "    pre_intent = pre_data[0]\n",
    "    pre_intent = id2intent[str(np.argmax(pre_intent))]\n",
    "    pre_slot = pre_data[1]\n",
    "    pre_slot = np.squeeze(pre_slot)[:len(x)]\n",
    "    pre_ner = []\n",
    "    for i in pre_slot:\n",
    "        pre_ner.append(id2slot[str(np.argmax(i))])\n",
    "    print('　text: {} \\n intent:{} \\n slot:{}'.format(x,pre_intent,pre_ner))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(x):\n",
    "    x = list(x)\n",
    "    pre_data = trans2labelid(char2id,x,max_sent_len)\n",
    "    pre_data = model.predict([pre_data])\n",
    "    pre_intent = pre_data[0]\n",
    "    pre_intent = id2intent[str(np.argmax(pre_intent))]\n",
    "    pre_slot = pre_data[1]\n",
    "    pre_slot = np.squeeze(pre_slot)[:len(x)]\n",
    "    pre_ner = []\n",
    "    for i in pre_slot:\n",
    "        if len(id2slot[str(np.argmax(i))]) > 2 :\n",
    "            pre_ner.append(id2slot[str(np.argmax(i))][2:])\n",
    "        else:\n",
    "            pre_ner.append(id2slot[str(np.argmax(i))])\n",
    "                        \n",
    "    print('text: {} \\n intent:{} \\n slot:{}'.format(x,pre_intent,pre_ner))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "　text: ['两', '小', '时', '后', '关', '闭', '风', '扇'] \n",
      " intent:Control-Humidifier_Gear \n",
      " slot:['B-time', 'B-time', 'B-time', 'B-time', 'B-color', 'I-mode', 'B-time', 'B-time']\n"
     ]
    }
   ],
   "source": [
    "inputs = '两小时后关闭风扇'\n",
    "predict(inputs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
